Skip to content

Latest commit

ย 

History

History
250 lines (192 loc) ยท 6.97 KB

File metadata and controls

250 lines (192 loc) ยท 6.97 KB

ํŠธ๋ฆฌ

ํŠธ๋ฆฌ๋Š” ๋น„์ˆœ์ฐจ์  ์ž๋ฃŒ๊ตฌ์กฐ๋กœ, ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์ถ”์ƒํ™”ํ•œ ๋ชจ๋ธ์ด๋‹ค.

๊ฐ€์žฅ ํ”ํ•œ ์˜ˆ์‹œ๋กœ๋Š” ๊ฐ€๊ณ„๋„ ํ˜น์€ ํšŒ์‚ฌ ์กฐ์ง ๊ตฌ์กฐ ์ •๋„๋ฅผ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์šฉ์–ด ์„ค๋ช…

ํŠธ๋ฆฌ๋Š” ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง„ ๋‹ค์ˆ˜์˜ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ์ตœ์ƒ์œ„ ๋…ธ๋“œ์ธ ๋ฃจํŠธ(root)๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋…ธํŠธ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค์ˆ˜์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ๊ณ , ์•„์˜ˆ ์—†์„ ์ˆ˜๋„ ์žˆ๋‹ค.

ํŠธ๋ฆฌ

  • ๋ฃจํŠธ(root): ์ตœ์ƒ์œ„ ๋…ธ๋“œ, ๋ถ€๋ชจ๊ฐ€ ์—†๋Š” ๋…ธ๋“œ

  • ๋‚ด๋ถ€ ๋…ธ๋“œ: ์ž์‹์ด ํ•˜๋‚˜ ์ด์ƒ์ด ์กด์žฌํ•˜๋Š” ๋…ธ๋“œ

  • ์™ธ๋ถ€ ๋…ธ๋“œ(leaf): ์ž์‹์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋…ธ๋“œ

  • ์กฐ์ƒ: ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•œ ์ƒ์œ„ ๋…ธ๋“œ๋ฅผ ์ผ์ปซ๋Š”๋‹ค.

  • ํ›„์†: ์กฐ์ƒ๊ณผ ๋ฐ˜๋Œ€๋กœ ํ•˜์œ„ ๋…ธ๋“œ๋ฅผ ์ผ์ปซ๋Š”๋‹ค.

  • ์„œ๋ธŒ ํŠธ๋ฆฌ: ๋…ธ๋“œ์™€ ํ›„์†์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ํ•œ ์Œ์˜ ์ž‘์€ ํŠธ๋ฆฌ

  • ๊นŠ์ด: ์กฐ์ƒ์˜ ๊ฐœ์ˆ˜, ๋ ˆ๋ฒจ๋กœ ๊ตฌ๋ถ„ ํ•˜๊ธฐ๋„ ํ•จ

  • ๋†’์ด: ๊นŠ์ด์˜ ์ตœ๋Œ€์น˜

์ด์ง„ ํŠธ๋ฆฌ์™€ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ

์ด์ง„ ํŠธ๋ฆฌ(binary tree): ์ขŒ, ์šฐ์ธก์— ๊ฐ๊ฐ ํ•˜๋‚˜์”ฉ ํ•˜์—ฌ ์ตœ๋Œ€ ๋‘ ๊ฐœ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง„ ํŠธ๋ฆฌ

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ(binary search tree): ์ด์ง„ ํŠธ๋ฆฌ์—์„œ ์ขŒ์ธก ์ž์‹ ๋…ธ๋“œ์—๋Š” ์ž‘์€ ๊ฐ’์„, ์šฐ์ธก ์ž์‹ ๋…ธ๋“œ์—๋Š” ๋” ํฐ ๊ฐ’์„ ๋“ค๊ณ  ์žˆ๋‹ค๋Š” ๊ทœ์น™์ด ์ถ”๊ฐ€๋œ ํŠธ๋ฆฌ

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ ๋งŒ๋“ค๊ธฐ

ํŠธ๋ฆฌ์˜ ๊ธฐ๋ณธ ํ‹€ ๊ตฌํ˜„

function Node(key) {
  this.key = key;
  this.left = null; // ์ขŒ์ธก ์ž์‹ ๋…ธ๋“œ
  this.right = null; // ์šฐ์ธก ์ž์‹ ๋…ธ๋“œ
}

function BinarySearchTree() {
  let root = null; // ์ตœ์ƒ๋‹จ ๋…ธ๋“œ
}

ํŠน์ • ํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„

function BinarySearchTree() {
  let root = null;

  this.insert = function (key) {
    const newNode = new Node(key);
    if (root === null) {
      // ๋ฃจํŠธ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ, ๋…ธ๋“œ๋ฅผ ๋ฃจํŠธ๋กœ ์ง€์ •
      root = newNode;
    } else {
      // ๊ทธ ์™ธ ๋…ธ๋“œ ์‚ฝ์ž…
      insertNode(root, newNode);
    }
  };
}

function insertNode(node, newNode) {
  //  ์ƒˆ๋กœ์šด ๋…ธ๋“œ์˜ key๊ฐ’๋ณด๋‹ค ํ˜„์žฌ ๋…ธ๋“œ์˜ key๊ฐ’์ด ํด ๊ฒฝ์šฐ
  if (newNode.key < node.key) {
    // ๋…ธ๋“œ์˜ ์ขŒ์ธก ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ ์ง€์ •
    if (node.left === null) {
      node.left = newNode;
    } else {
      // ๋น„์–ด์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ขŒ์ธก ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ
      insertNode(node.left, newNode);
    }
  } else {
    // ๋…ธ๋“œ์˜ ์šฐ์ธก ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ ์ง€์ •
    if (node.right === null) {
      node.right = newNode;
    } else {
      // ๋น„์–ด์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ ์šฐ์ธก ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ
      insertNode(node.right, newNode);
    }
  }
}

ํŠธ๋ฆฌ ์ˆœํšŒ ๊ตฌํ˜„

ํŠธ๋ฆฌ์˜ ์ˆœํšŒ๋ž€, ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜์—ฌ ์–ด๋– ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํŠธ๋ฆฌ ์ˆœํšŒ๋ผ๊ณ  ํ•œ๋‹ค.

ํŠธ๋ฆฌ์˜ ์ˆœํšŒ ๋ฐฉ๋ฒ•์—๋Š” ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

์ค‘์œ„ ์ˆœํšŒ

์ค‘์œ„ ์ˆœํšŒ๋Š” ๋…ธ๋“œ๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ, ์ฆ‰ ์ž‘์€ ๊ฐ’์—์„œ ํฐ ๊ฐ’ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

function inOrderTraverseNode(node, callback) {
  // ๋…ธ๋“œ๊ฐ€ null์ด๋ผ๋ฉด ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์ค‘๋‹จํ•œ๋‹ค
  if (node === null) return;

  // ์ขŒ์ธก ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ๋ฐฉ๋ฌธ
  inOrderTraverseNode(node.left, callback);
  // ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  callback(node.key);
  // ์šฐ์ธก ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  inOrderTraverseNode(node.right, callback);
}

์ค‘์œ„ ์ˆœํšŒ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ถœ๋ ฅํ•  ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

H D I B E A F C G

์ „์œ„ ์ˆœํšŒ

์ „์œ„ ์ˆœํšŒ๋Š” ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ์ž๊ธฐ ์ž์‹ ์„ ๋จผ์ € ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

function preOrderTraverseNode(node, callback) {
  // ๋…ธ๋“œ๊ฐ€ null์ด๋ผ๋ฉด ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์ค‘๋‹จํ•œ๋‹ค
  if (node === null) return;

  // ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ๋ฐฉ๋ฌธ
  callback(node.key);
  // ์ขŒ์ธก ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  preOrderTraverseNode(node.left, callback);
  // ์šฐ์ธก ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  preOrderTraverseNode(node.right, callback);
}

์ „์œ„ ์ˆœํšŒ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ถœ๋ ฅํ•  ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

A B D H I E C F G

ํ›„์œ„ ์ˆœํšŒ

ํ›„์œ„ ์ˆœํšŒ๋Š” ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ชจ๋‘ ๋ฐฉ๋ฌธํ•œ ๋’ค ์ž๊ธฐ ์ž์‹ ์„ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

function postOrderTraverseNode(node, callback) {
  // ๋…ธ๋“œ๊ฐ€ null์ด๋ผ๋ฉด ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์ค‘๋‹จํ•œ๋‹ค
  if (node === null) return;

  // ์ขŒ์ธก ๋…ธ๋“œ๋ฅผ ๋จผ์ € ๋ฐฉ๋ฌธ
  postOrderTraverseNode(node.left, callback);
  // ์šฐ์ธก ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  postOrderTraverseNode(node.right, callback);
  // ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  callback(node.key);
}

ํ›„์œ„ ์ˆœํšŒ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ถœ๋ ฅํ•  ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

H I D E B F G C A

ํŠธ๋ฆฌ ๋…ธ๋“œ ๊ฒ€์ƒ‰ ๊ตฌํ˜„

ํŠธ๋ฆฌ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

์ตœ์†Ÿ๊ฐ’, ์ตœ๋Œ“๊ฐ’ ์ฐพ๊ธฐ

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ํŠน์ง•์„ ์ž˜ ๋ณด๋ฉด, ์ตœ์†Ÿ๊ฐ’ ํ˜น์€ ์ตœ๋Œ“๊ฐ’์„ ํ•œ ๋ˆˆ์— ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ตœํ•˜์œ„ ๋ ˆ๋ฒจ์˜ ๋งจ ์ขŒ์ธก ๋…ธ๋“œ๊ฐ€ ์ตœ์†Ÿ๊ฐ’, ์ตœํ•˜์œ„ ๋ ˆ๋ฒจ์˜ ๋งจ ์šฐ์ธก ๋…ธ๋“œ๊ฐ€ ์ตœ๋Œ“๊ฐ’์ด๋‹ค.

function minNode(node) {
  if (!node) return null;

  while (node.left !== null) {
    node = node.left;
  }
  return node.key;
}

function maxNode(node) {
  if (!node) return null;

  while (node.right !== null) {
    node = node.right;
  }
  return node.key;
}

๊ฐ๊ฐ์˜ ๋ฉ”์†Œ๋“œ๋Š” ๊ธฐ์ค€์ด ๋  node๋ฅผ ๋„˜๊ฒจ๋ฐ›๋Š”๋ฐ, ์ด๋Ÿฐ ์‹์œผ๋กœ ํŠธ๋ฆฌ ํ˜น์€ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์ตœ์†Œ, ์ตœ๋Œ“๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ • ๊ฐ’ ์ฐพ๊ธฐ

function searchNode(node, key) {
  // ๋…ธ๋“œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ false
  if (node === null) return false;

  // ํŠน์ • ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ
  if (key < node.key) {
    return searchNode(node.left, key);
  }
  // ํŠน์ • ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ๋ณด๋‹ค ํด ๊ฒฝ์šฐ
  else if (node.key < key) {
    return searchNode(node.right, key);
  }
  // ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ ํŠน์ • ๊ฐ’์ผ ๊ฒฝ์šฐ
  return true;
}

๋…ธ๋“œ ์‚ญ์ œ

์•„๋งˆ ๊ฐ€์žฅ ๋ณต์žกํ•  ๋“ฏ

function removeNode(node, key) {
  if (node === null) return null;

  // ํŠน์ • ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ
  if (key < node.key) {
    node.left = removeNode(node.left, key);
    return node;
  }

  // ํŠน์ • ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ๋ณด๋‹ค ํด ๊ฒฝ์šฐ
  if (node.key < key) {
    node.right = removeNode(node.right, key);
    return node;
  }
  // ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ ํŠน์ • ๊ฐ’์ผ ๊ฒฝ์šฐ
  // 1. ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ์ผ ๊ฒฝ์šฐ
  if (node.left === null && node.right === null) {
    // ๋นˆ ๋…ธ๋“œ(null)๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
    return null;
  }
  // 2. ์ž์‹์ด ํ•˜๋‚˜ ์žˆ๋Š” ๋…ธ๋“œ์ผ ๊ฒฝ์šฐ
  if (node.left === null || node.right === null) {
    // ๋น„์–ด์žˆ์ง€ ์•Š์€ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    return node.left || node.right;
  }
  // 3. ์ž์‹์ด ๋‘˜์ธ ๋…ธ๋“œ์ผ ๊ฒฝ์šฐ
  // ์šฐ์ธก ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์ตœ์†Ÿ๊ฐ’ ๊ฒ€์ƒ‰
  const changeData = minNode(node.right);
  // ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’์„ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์ตœ์†Ÿ๊ฐ’์œผ๋กœ ๊ต์ฒด
  node.key = changeData.key;
  // ์šฐ์ธก ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ ์ค‘๋ณต ๋ฐ์ดํ„ฐ ์ œ๊ฑฐ
  node.right = removeNode(node.right, changeData.key);
  // ํ˜„์žฌ ๋…ธ๋“œ ๋ฐ˜ํ™˜
  return node;
}